/* eslint-disable react-hooks/rules-of-hooks */
/* eslint-disable no-case-declarations */
/* eslint-disable react/jsx-key */
/* eslint-disable array-callback-return */
/* eslint-disable guard-for-in */
/* eslint-disable eqeqeq */
import { doFetch } from '@/utils/doFetch';
import {
  LightFilter,
  ProFormDatePicker,
  ProFormDateRangePicker,
  ProFormDateTimePicker,
  ProFormDateTimeRangePicker,
  ProFormDigit,
  ProFormSelect,
  ProFormText,
  ProFormTimePicker,
  ProFormTreeSelect,
} from '@ant-design/pro-components';
import { Form } from 'antd';
import dayjs from 'dayjs';
import { useMemo } from 'react';

// tree遍历
function treeForeach(tree, func) {
  tree.forEach((data) => {
    func(data);
    data.children && treeForeach(data.children, func); // 遍历子树
  });
}

function upperCase(str) {
  const newStr = str.slice(0, 1).toUpperCase() + str.slice(1);
  return newStr;
}

const quarterFormat = 'YYYY-MM-DD',
  weekFormat = 'YYYY-MM-DD';

function LightFilters(props) {
  let {
    formRef,
    defaultFormValue = {},
    fields,
    colProps = { xs: 24, sm: 24, md: 12, lg: 12, xl: 12, xxl: 12 },
    onValuesChange = () => {},
  } = props;

  const columns = useMemo(() => {
    return fields
      ?.filter((it) => it.valueType != 'option')
      ?.filter((it) => it.search !== false)
      ?.filter((it) => it.hideInSearch !== true);
  }, [fields]);

  const [form] = Form.useForm();

  return (
    <LightFilter
      formRef={formRef}
      placement="bottomLeft"
      form={form}
      // isKeyPressSubmit={true}
      onValuesChange={(changedValues, allValues) => {
        onValuesChange?.(changedValues, allValues);
      }}
    >
      {columns?.map((item) => {
        let key = item?.valueType ? upperCase(item?.valueType) : 'Input';
        let name = item?.key ?? item?.dataIndex ?? '';

        let curoption = item?.options ?? null;
        let ifs = curoption?.linkParams;

        //联动逻辑
        let curlinkparams = curoption?.linkParams ?? null, //获取linkParams下声明的key
          extraParams = curoption?.extraParams ?? {},
          params = {};
        if (curlinkparams) {
          Object.entries(curlinkparams).map(([key, realkey]) => {
            const forval = Form.useWatch(key, form);
            if (!realkey) {
              params[key] = forval;
            } else {
              params[realkey] = forval;
            }
          });
        }

        switch (key) {
          case 'Input':
            return (
              <ProFormText
                
                secondary={item?.secondary}
                initialValue={item?.initialValue}
                fieldProps={item?.fieldProps}
                name={name}
                label={item.title}
                placeholder={`请输入${item.title}`}
              ></ProFormText>
            );
          case 'Digit':
            return (
              <ProFormDigit
                secondary={item?.secondary}
                initialValue={item?.initialValue}
                fieldProps={item?.fieldProps}
                name={name}
                label={item.title}
                placeholder={`请输入${item.title}`}
              />
            );
          case 'Date':
            return (
              <ProFormDatePicker
                secondary={item?.secondary}
                initialValue={item?.initialValue}
                fieldProps={item?.fieldProps}
                name={name}
                label={item.title}
                placeholder={`请选择${item.title}`}
              />
            );
          case 'DateWeek':
            const customWeekStartEndFormat = (value) =>
              `${dayjs(value).startOf('week').format(weekFormat)} ~ ${dayjs(
                value,
              )
                .endOf('week')
                .format(weekFormat)}`;
            return (
              <ProFormDatePicker
                secondary={item?.secondary}
                initialValue={item?.initialValue}
                fieldProps={{
                  ...item?.fieldProps,
                  picker: 'week',
                  format: customWeekStartEndFormat,
                }}
                name={name}
                label={item.title}
                placeholder={`请选择${item.title}`}
              />
            );
          case 'DateMonth':
            return (
              <ProFormDatePicker
                secondary={item?.secondary}
                initialValue={item?.initialValue}
                fieldProps={{
                  ...item?.fieldProps,
                  picker: 'month',
                  format: 'YYYY-MM',
                }}
                name={name}
                label={item.title}
                placeholder={`请选择${item.title}`}
              />
            );
          case 'DateQuarter':
            const customQuarterStartEndFormat = (value) =>
              `${dayjs(value)
                .startOf('quarter')
                .format(quarterFormat)} ~ ${dayjs(value)
                .endOf('quarter')
                .format(quarterFormat)}`;
            return (
              <ProFormDatePicker
                secondary={item?.secondary}
                initialValue={item?.initialValue}
                fieldProps={{
                  ...item?.fieldProps,
                  picker: 'quarter',
                  format: customQuarterStartEndFormat,
                }}
                name={name}
                label={item.title}
                placeholder={`请选择${item.title}`}
              />
            );
          case 'DateYear':
            return (
              <ProFormDatePicker
                secondary={item?.secondary}
                initialValue={item?.initialValue}
                fieldProps={{
                  ...item?.fieldProps,
                  picker: 'year',
                  format: 'YYYY',
                }}
                name={name}
                label={item.title}
                placeholder={`请选择${item.title}`}
              />
            );
          case 'DateTime':
            return (
              <ProFormDateTimePicker
                secondary={item?.secondary}
                initialValue={item?.initialValue}
                fieldProps={item?.fieldProps}
                name={name}
                label={item.title}
                placeholder={`请选择${item.title}`}
              />
            );
          case 'DateRange':
            return (
              <ProFormDateRangePicker
                initialValue={item?.initialValue ?? undefined}
                fieldProps={item?.fieldProps}
                name={name}
                label={item.title}
                placeholder={['开始日期', '结束日期']}
              />
            );
          case 'DateTimeRange':
            return (
              <ProFormDateTimeRangePicker
                secondary={item?.secondary}
                initialValue={item?.initialValue}
                fieldProps={item?.fieldProps}
                name={name}
                label={item.title}
                placeholder={['开始时间', '结束时间']}
              />
            );
          case 'Time':
            return (
              <ProFormTimePicker
                secondary={item?.secondary}
                initialValue={item?.initialValue}
                fieldProps={item?.fieldProps}
                name={name}
                label={item.title}
                placeholder={`请选择${item.title}`}
              />
            );
          case 'TimeRange':
            return (
              <ProFormTimePicker.RangePicker
                secondary={item?.secondary}
                initialValue={item?.initialValue}
                fieldProps={item?.fieldProps}
                name={name}
                label={item.title}
                placeholder={['开始时间', '结束时间']}
              />
            );
          case 'Select':
            if (ifs) {
              return (
                <ProFormSelect
                  secondary={item?.secondary}
                  initialValue={item?.initialValue}
                  convertValue={(value) => {
                    return item?.fieldProps?.mode == 'multiple'
                      ? !value
                        ? []
                        : value
                      : null;
                  }}
                  fieldProps={{
                    ...(item.fieldProps ?? {}),
                    filterOption: (input, option) =>
                      (option?.label ?? '').includes(input),
                    showSearch: true,
                  }}
                  name={name}
                  label={item.title}
                  placeholder={`请选择${item.title}`}
                  params={params}
                  request={async (parse) => {
                    let result = { ...parse };
                    delete result.keyWords;
                    let res = await doFetch({
                      url: curoption?.path,
                      params: {
                        ...result,
                        ...extraParams,
                      },
                    });
                    let newOptions = res?.data?.dataList ?? [];
                    let curval = formRef?.current?.getFieldValue(name),
                      ifclean;

                    if (Array.isArray(curval)) {
                      ifclean = newOptions
                        ?.map((it) => it.value)
                        .filter?.((it) => {
                          return curval?.includes(it);
                        });
                    } else {
                      ifclean = newOptions.filter(
                        (it) => it.value == curval,
                      )?.[0]?.value;
                    }
                    formRef?.current?.setFieldsValue({
                      [name]: ifclean,
                    });
                    return newOptions;
                  }}
                  debounceTime={300}
                />
              );
            }
            return (
              <ProFormSelect
                secondary={item?.secondary}
                initialValue={item?.initialValue}
                convertValue={(value) => {
                  return item?.fieldProps?.mode == 'multiple'
                    ? !value
                      ? []
                      : value
                    : null;
                }}
                fieldProps={{
                  filterOption: (input, option) =>
                    (option?.label ?? '').includes(input),
                  showSearch: true,
                }}
                name={name}
                label={item.title}
                placeholder={`请选择${item.title}`}
                request={async () => {
                  if (Array.isArray(curoption)) {
                    return [...curoption];
                  }

                  let list = await doFetch({
                    url: curoption?.path,
                    params: curoption?.params,
                  });
                  return list?.data?.dataList ?? [];
                }}
              />
            );
          case 'TreeSelect':
            if (ifs) {
              return (
                <ProFormTreeSelect
                  secondary={item?.secondary}
                  initialValue={item?.initialValue}
                  convertValue={(value) => {
                    return item?.fieldProps?.mode == 'multiple'
                      ? !value
                        ? []
                        : value
                      : null;
                  }}
                  fieldProps={{
                    ...item?.fieldProps,
                    allowClear: true,
                    fieldNames: {
                      label: 'title',
                      value: 'key',
                      children: 'children',
                    },
                    showSearch: false,
                  }}
                  name={name}
                  label={item.title}
                  placeholder={`请选择${item.title}`}
                  params={params}
                  request={async (params) => {
                    let result = { ...params };
                    delete result.keyWords;

                    let res = await doFetch({
                      url: curoption?.path,
                      params: {
                        ...result,
                        ...extraParams,
                      },
                    });
                    let newOptions = res?.data?.dataList ?? [];

                    let curval = formRef?.current?.getFieldValue(name),
                      ifclean;
                    //树结构所有value提取到数组
                    let allvalue = [];
                    treeForeach(res?.data?.dataList, (node) => {
                      allvalue.push(node?.key);
                    });

                    //过滤存在的value
                    if (Array.isArray(curval)) {
                      ifclean = allvalue?.filter?.((it) => {
                        return curval?.includes(it);
                      });
                    } else {
                      ifclean = allvalue?.filter?.((it) => it == curval)?.[0];
                    }

                    formRef?.current?.setFieldsValue({ [name]: ifclean });

                    return newOptions;
                  }}
                  debounceTime={300}
                  width={120}
                />
              );
            }
            return (
              <ProFormTreeSelect
                secondary={item?.secondary}
                initialValue={item?.initialValue}
                convertValue={(value) => {
                  return item?.fieldProps?.mode == 'multiple'
                    ? !value
                      ? []
                      : value
                    : null;
                }}
                fieldProps={{
                  ...item?.fieldProps,
                  allowClear: true,
                  fieldNames: {
                    label: 'title',
                    value: 'key',
                    children: 'children',
                  },
                  showSearch: false,
                }}
                name={name}
                label={item.title}
                placeholder={`请选择${item.title}`}
                request={async () => {
                  if (Array.isArray(curoption)) {
                    return [...curoption];
                  }

                  let list = await doFetch({
                    url: curoption?.path,
                    params: curoption?.params,
                  });
                  return list?.data?.dataList ?? [];
                }}
              />
            );

          default:
            break;
        }
      })}
    </LightFilter>
  );
}

export default LightFilters;
